package com.usefullc.extinguisher.service;

import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.usefullc.common.enums.RecentDateEnum;
import com.usefullc.common.enums.YesNoEnum;
import com.usefullc.common.util.DateUtils;
import com.usefullc.common.util.NumberUtil;
import com.usefullc.common.util.date.DatePattern;
import com.usefullc.common.util.date.Pattern;
import com.usefullc.common.vo.AxisItemVo;
import com.usefullc.common.vo.AxisVo;
import com.usefullc.common.vo.AxisWrapperVo;
import com.usefullc.extinguisher.constant.ExtinguisherConstant;
import com.usefullc.extinguisher.domain.FireDeviceAuditRecord;
import com.usefullc.extinguisher.enums.DeviceAuditRecordStatusEnum;
import com.usefullc.extinguisher.mapper.FireDeviceAuditRecordMapper;
import com.usefullc.extinguisher.query.FireDeviceAuditRecordQuery;
import com.usefullc.extinguisher.query.FireDeviceAuditStatQuery;
import com.usefullc.extinguisher.vo.FireDeviceAuditRecordVo;
import com.usefullc.extinguisher.vo.FireDeviceAuditStatVo;
import com.usefullc.extinguisher.vo.FireDeviceTypeStatVo;
import com.usefullc.extinguisher.vo.IndexChartVo;
import com.usefullc.system.domain.DataDict;
import com.usefullc.system.domain.JobTemplate;
import com.usefullc.system.entity.Pager;
import com.usefullc.system.enums.JobTemplatePeriodEnum;
import com.usefullc.system.query.BaseQuery;
import com.usefullc.system.query.JobTemplateQuery;
import com.usefullc.system.service.*;
import com.usefullc.system.validator.UsefulPropertyVerify;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collector;
import java.util.stream.Collectors;

/**
 * 设备检查汇总服务类
 *
 * @author: 星空
 * @date: 2022-09-08
 */
@Service
public class FireDeviceAuditStatService extends AbstractBizService<FireDeviceAuditRecordMapper, FireDeviceAuditRecord, FireDeviceAuditRecordQuery> {


    @Autowired
    private JobTemplateService jobTemplateService;

    @Autowired
    private FireDeviceAuditRecordService fireDeviceAuditRecordService;

    @Autowired
    private DataDictService dataDictService;

    @Autowired
    private FireDeviceService fireDeviceService;

    @Override
    protected QueryWrapper<FireDeviceAuditRecord> getQueryWrapper(FireDeviceAuditRecordQuery query) {
        QueryWrapper<FireDeviceAuditRecord> queryWrapper = super.getQueryWrapper(query);
        return queryWrapper;
    }


    //获取当前时间统计记录
    public List<FireDeviceAuditStatVo> list() {
        //先获取作业记录
        JobTemplateQuery jobTemplateQuery = new JobTemplateQuery();
        jobTemplateQuery.setCategory(ExtinguisherConstant.JOB_CATEGORY_FIRE);  //0 表示消防
        jobTemplateQuery.setEnabled(YesNoEnum.YES.getCode());  //
        List<JobTemplate> jobDataList = jobTemplateService.findAll(jobTemplateQuery);
        List<FireDeviceAuditStatVo> dataList = new ArrayList<>();
        for (JobTemplate jobTemplate : jobDataList) {
            FireDeviceAuditRecordQuery fireDeviceAuditRecordQuery = new FireDeviceAuditRecordQuery();
            fireDeviceAuditRecordQuery.setJobId(jobTemplate.getId());
            FireDeviceAuditRecord fireDeviceAuditRecord = fireDeviceAuditRecordService.findOne(fireDeviceAuditRecordQuery);
            if (fireDeviceAuditRecord == null) {
                continue;
            }
            FireDeviceAuditStatVo fireDeviceAuditStatVo = this.findStatByBatchNo(jobTemplate, fireDeviceAuditRecord.getBatchNo());
            dataList.add(fireDeviceAuditStatVo);
        }
        return dataList;
    }


    public Pager<FireDeviceAuditStatVo> listHisPage(Long jobId) {
        FireDeviceAuditStatQuery query = new FireDeviceAuditStatQuery();
        query.setJobId(jobId);
        Pager<Long> pager = this.findByPage(query, new IPageCallback<Long>() {
            @Override
            public Long count(BaseQuery q) {
                return getBaseMapper().findByGroupCount(q);
            }

            @Override
            public List<Long> dataList(BaseQuery q, Pager p) {
                return getBaseMapper().findByGroup(q, p);
            }
        });
        Pager<FireDeviceAuditStatVo> newPager = new Pager<>(pager);
        List<Long> dataList = pager.getDataList();

        JobTemplate jobTemplate = jobTemplateService.findById(jobId);

        if (CollectionUtils.isNotEmpty(dataList)) {
            List<FireDeviceAuditStatVo> newDataList = new ArrayList<>();
            for (Long batchNo : dataList) {
                FireDeviceAuditStatVo fireDeviceAuditStatVo = this.findStatByBatchNo(jobTemplate, batchNo);
                newDataList.add(fireDeviceAuditStatVo);
            }
            newPager.setDataList(newDataList);
        }
        return newPager;
    }


    public IndexChartVo getIndexChartVo(){
        IndexChartVo indexChartVo = new IndexChartVo();
        //
        int dayNum = 7;  //默认最近7天
        DateTime endDateTime = DateUtil.date();
        DateTime startDateTime = DateUtil.offsetDay(endDateTime, -dayNum);
        Integer auditPassNum = this.fireDeviceAuditRecordService.getBaseMapper().findTotalStatNumByRangeDateTime(DeviceAuditRecordStatusEnum.AUDITED.getCode(),startDateTime, endDateTime);
        Integer auditErrorNum = this.fireDeviceAuditRecordService.getBaseMapper().findTotalStatNumByRangeDateTime(DeviceAuditRecordStatusEnum.ERROR.getCode(),startDateTime, endDateTime);
        auditPassNum = NumberUtil.getNumber(auditPassNum);
        auditErrorNum = NumberUtil.getNumber(auditErrorNum);
        Integer totalAuditNum = NumberUtil.add(auditErrorNum, auditPassNum);
        Integer totalAvgAuditNum = totalAuditNum / dayNum;
        Integer auditAvgPassNum = auditPassNum / dayNum;
        Integer auditAvgErrorNum = auditErrorNum / dayNum;



        Integer auditPersonNum = this.fireDeviceAuditRecordService.getBaseMapper().findTotalPersonNumByRangeDateTime(startDateTime, endDateTime);
        auditPersonNum = NumberUtil.getNumber(auditPersonNum);
        Integer auditAvgPersonNum = auditPersonNum / dayNum;

        indexChartVo.setAuditNum(totalAuditNum);
        indexChartVo.setAuditAvgNum(totalAvgAuditNum);
        indexChartVo.setAuditPassNum(auditPassNum);
        indexChartVo.setAuditAvgPassNum(auditAvgPassNum);
        indexChartVo.setAuditErrorNum(auditErrorNum);
        indexChartVo.setAuditAvgErrorNum(auditAvgErrorNum);
        indexChartVo.setAuditPersonNum(auditPersonNum);
        indexChartVo.setAuditNumPerPerson(auditAvgPersonNum);
        return indexChartVo;
    }

    public AxisWrapperVo auditTrendChart(FireDeviceAuditRecordQuery query) {
        String title = "作业中检查通过趋势";
        if (query.getStatus() == DeviceAuditRecordStatusEnum.ERROR.getCode()) {
            title = "作业中检查异常趋势";
        }
        AxisWrapperVo axisWrapperVo = new AxisWrapperVo();
        axisWrapperVo.setLegend(title);
        JobTemplateQuery jobTemplateQuery = new JobTemplateQuery();
        jobTemplateQuery.setCategory(ExtinguisherConstant.JOB_CATEGORY_FIRE);  //0 表示消防
        jobTemplateQuery.setEnabled(YesNoEnum.YES.getCode());  //
        jobTemplateQuery.setIds(query.getJobIds());
        List<JobTemplate> jobDataList = jobTemplateService.findAll(jobTemplateQuery);
        if (CollectionUtils.isEmpty(jobDataList)) {
            return axisWrapperVo;
        }
        Integer recentDay = query.getRecentDay();
        RecentDateEnum recentDateEnum = RecentDateEnum.getByCode(recentDay);
        int distanceNum = recentDateEnum.getNum();
        DateTime endDateTime = DateUtil.date();
        DateTime startDateTime = DateUtil.offset(endDateTime, DateField.of(recentDateEnum.getField()),-distanceNum-1);

//        List<FireDeviceAuditStatVo> dataList = new ArrayList<>();

        List<AxisVo> axisVoList = new ArrayList<>();
        axisWrapperVo.setItemList(axisVoList);
        for (JobTemplate jobTemplate : jobDataList) {

            AxisVo axisVo = new AxisVo();
            axisVoList.add(axisVo);
            axisVo.setLegend(jobTemplate.getName());
            List<AxisItemVo> itemList = new ArrayList<>();
            axisVo.setItemList(itemList);


            //获取坐标数据
            FireDeviceAuditRecordQuery fireDeviceAuditRecordQuery = new FireDeviceAuditRecordQuery();
            fireDeviceAuditRecordQuery.setJobId(jobTemplate.getId());
            fireDeviceAuditRecordQuery.setStatus(query.getStatus());
            fireDeviceAuditRecordQuery.setGmtAuditStart(DateUtils.format(startDateTime, DatePattern.yyyy_MM_dd));
            fireDeviceAuditRecordQuery.setGmtAuditEnd(DateUtils.format(endDateTime, DatePattern.yyyy_MM_dd));

            List<FireDeviceAuditRecord> fireDeviceAuditRecords = this.fireDeviceAuditRecordService.findAll(fireDeviceAuditRecordQuery);
            Map<String, Long> statTimeNumMap = new HashMap<>();
            //分组
            if (CollectionUtils.isNotEmpty(fireDeviceAuditRecords)) {
                statTimeNumMap = fireDeviceAuditRecords.stream().collect(Collectors.groupingBy(data -> DateUtil.format(data.getGmtAudit(), recentDateEnum.getFormat()), Collectors.counting()));
            }


            //时间单位
//            List<String> timeList = new ArrayList<>();
            for (int i = 1; i <=distanceNum; i++) {
                DateTime dateTime = DateUtil.offset(endDateTime, DateField.of(recentDateEnum.getField()), -(distanceNum-i));
                String time = DateUtil.format(dateTime, recentDateEnum.getFormat());
                Long num = statTimeNumMap.get(time);
                if(num == null){
                    num = 0L;
                }
                AxisItemVo axisItemVo = new AxisItemVo();
                axisItemVo.setAxisX(time);
                axisItemVo.setAxisY(new BigDecimal(num));
                itemList.add(axisItemVo);
            }


        }

//        List<AxisVo> axisVoList = new ArrayList<>();
//        axisWrapperVo.setItemList(axisVoList);
//        for (int x = 0; x < 5; x++) {
//            AxisVo axisVo = new AxisVo();
//            axisVoList.add(axisVo);
//            axisVo.setLegend("作业" + (char) (65 + x));
//            List<AxisItemVo> itemList = new ArrayList<>();
//
//            for (int i = 0; i < 30; i++) {
//                AxisItemVo axisItemVo = new AxisItemVo();
//                axisItemVo.setAxisX("" + (i + 1));
//                axisItemVo.setAxisY(new BigDecimal(RandomUtils.nextLong(10, 100)));
//                itemList.add(axisItemVo);
//            }
//            axisVo.setItemList(itemList);
//        }
        return axisWrapperVo;
    }

    public List<Map<String,Object>> deviceNumList(){
        List<Map<String,Object>> result = new ArrayList<>();
        //获取电厂列表
        List<DataDict> dictPositionList = dataDictService.getChildrenByValue(ExtinguisherConstant.DIC_FIRE_DEVICE_POSITION);
        List<DataDict> dictTypeList = dataDictService.getChildrenByValue(ExtinguisherConstant.DICT_FIRE_DEVICE_TYPE);
        List<String> typeList = dictTypeList.stream().map(data -> data.getValue()).collect(Collectors.toList());
//        Map<String,Object> dataMap = new LinkedHashMap<>();
        Map<String,Object> dataMap = new LinkedHashMap<>();
        result.add(dataMap);
        dataMap.put("a","电厂");
        for (DataDict dataDict : dictTypeList) {
            dataMap.put(dataDict.getValue(),dataDict.getName());
        }

        for (DataDict positionDict : dictPositionList) {
            dataMap = new LinkedHashMap<>();
            dataMap.put("a",positionDict.getName());
            List<FireDeviceTypeStatVo> typeMapList = fireDeviceService.getBaseMapper().findNumGroupByType(positionDict.getCode());
            Map<String, Integer> dbDataMap = typeMapList.stream().collect(Collectors.toMap(data->data.getType().toString(), FireDeviceTypeStatVo::getNum));
            for (String type : typeList) {
                Integer num = dbDataMap.get(type);
                num = NumberUtil.getNumber(num);
                dataMap.put(type,num);
            }
            result.add(dataMap);
        }
        return result;

    }


    private FireDeviceAuditStatVo findStatByBatchNo(JobTemplate jobTemplate, Long batchNo) {
        Long jobId = jobTemplate.getId();
        Integer notAuditNum = this.fireDeviceAuditRecordService.getBaseMapper().findStatNumByBatchNo(jobId, batchNo, DeviceAuditRecordStatusEnum.NOT_AUDIT.getCode());
        Integer auditedNum = this.fireDeviceAuditRecordService.getBaseMapper().findStatNumByBatchNo(jobId, batchNo, DeviceAuditRecordStatusEnum.AUDITED.getCode());
        Integer errorNum = this.fireDeviceAuditRecordService.getBaseMapper().findStatNumByBatchNo(jobId, batchNo, DeviceAuditRecordStatusEnum.ERROR.getCode());
        FireDeviceAuditStatVo fireDeviceAuditStatVo = new FireDeviceAuditStatVo();
        fireDeviceAuditStatVo.setJobId(jobId);
        fireDeviceAuditStatVo.setJobName(jobTemplate.getName());
        Integer period = jobTemplate.getPeriod();
        JobTemplatePeriodEnum jobTemplatePeriodEnum = JobTemplatePeriodEnum.getByCode(period);
        fireDeviceAuditStatVo.setPeriodName(jobTemplatePeriodEnum.getValue());
        String periodTime = "";
        if (period == JobTemplatePeriodEnum.WEEK.getCode()) {
            int weekOfYear = DateUtil.weekOfYear(DateUtil.date(batchNo));
            periodTime = DateUtil.year(DateUtil.date(batchNo)) + "-" + weekOfYear;
        } else if (period == JobTemplatePeriodEnum.QUARTER.getCode()) {
            periodTime = DateUtil.yearAndQuarter(DateUtil.date(batchNo));
        } else if (period == JobTemplatePeriodEnum.CUSTOM.getCode()) {  //todo
        } else {
            periodTime = DateFormatUtils.format(batchNo, jobTemplatePeriodEnum.getFormat());
        }
        fireDeviceAuditStatVo.setPeriodTime(periodTime);
        fireDeviceAuditStatVo.setDoneNum(auditedNum);
        fireDeviceAuditStatVo.setUndoneNum(notAuditNum);
        fireDeviceAuditStatVo.setErrorNum(errorNum);
        return fireDeviceAuditStatVo;
    }


}
